package com.ansion.baseui.base;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.ansion.basetool.preconditions.Preconditions;
import com.ansion.baseui.base.click.AvoidDoubleClickListener;
import com.ansion.baseui.base.loading.CustomAlertDialog;

/**
 * @author zhaoyuntao
 * date 2021/6/28
 */
public abstract class TBaseFragment extends Fragment implements View.OnClickListener, TOnBackPressListener, ToastSupport, LoadingSupport {

    private CustomAlertDialog loadingDialog;

    @Override
    final public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        //Don't add judgement to activity cast.
        Activity baseActivity = getActivity();
        if (baseActivity instanceof TBaseActivity) {
            ((TBaseActivity) baseActivity).addOnBackPressListener(this);
        }
        onAttachedToActivity(context);
    }

    protected void onAttachedToActivity(@NonNull Context context) {

    }

    @Override
    final public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(initContentView(inflater, container, savedInstanceState), container, false);
    }

    @Override
    final public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        onFragmentCreated(view, savedInstanceState);
    }

    private void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        beforeInitView(view, savedInstanceState);
        initView_base(view, savedInstanceState);
        initData_base(view, savedInstanceState);
    }

    protected void beforeInitView(@NonNull View view, @Nullable Bundle savedInstanceState) {
    }

    protected void initView_base(@NonNull View view, Bundle savedInstanceState) {
    }

    protected void initData_base(@NonNull View view, Bundle savedInstanceState) {
    }

    @LayoutRes
    protected abstract int initContentView(LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState);

    protected <T extends View> T findViewById(@IdRes int resId) {
        View rootView = getView();
        if (rootView != null) {
            return rootView.findViewById(resId);
        } else {
            return null;
        }
    }

    protected void registerOnClickListener(@IdRes int resId) {
        View rootView = getView();
        if (rootView != null) {
            rootView.findViewById(resId).setOnClickListener(new AvoidDoubleClickListener() {
                @Override
                public void onClickView(View view) {
                    TBaseFragment.this.onClick(view);
                }
            });
        }
    }

    @Override
    public Activity activity() {
        return getActivity();
    }

    @Override
    final public CustomAlertDialog getLoadingDialog() {
        return loadingDialog;
    }

    @Override
    final public void onSetLoadingDialog(@Nullable CustomAlertDialog loadingDialog) {
        this.loadingDialog = loadingDialog;
    }

    protected Intent getIntent() {
        Activity activity = getActivity();
        if (activity != null) {
            return activity.getIntent();
        } else {
            return null;
        }
    }

    final protected Bundle getBundle() {
        Intent intent = getIntent();
        if (intent == null) {
            return null;
        }
        return intent.getExtras();
    }

    final protected Bundle getBundleIfNullFinish() {
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return null;
        }
        Bundle bundle = intent.getExtras();
        if (bundle == null) {
            finish();
        }
        return bundle;
    }

    final protected String getStringFromBundle(String key) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return null;
        }
        return bundle.getString(key);
    }

    final protected String getStringFromBundle(String key, boolean remove) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return null;
        }
        String value = bundle.getString(key);
        if (remove) {
            bundle.remove(key);
        }
        return value;
    }

    final protected int getIntFromBundle(String key, int defautValue) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defautValue;
        }
        return bundle.getInt(key);
    }

    final protected String getStringFromIntentIfNullFinish(String key) {
        Intent intent = getIntent();
        if (intent == null || !intent.hasExtra(key) || TextUtils.isEmpty(intent.getStringExtra(key))) {
            finish();
            return null;
        }
        return intent.getStringExtra(key);
    }

    final protected String getStringFromIntentIfNullThrowException(String key) {
        Intent intent = getIntent();
        Preconditions.checkNotNull(intent);
        Preconditions.checkNotEmpty(intent.getStringExtra(key));
        return intent.getStringExtra(key);
    }

    final protected boolean getBooleanFromBundle(String key) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return false;
        }
        return bundle.getBoolean(key);
    }

    final protected boolean getBooleanFromBundleIfNullFinish(String key) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            finish();
            return false;
        }
        return bundle.getBoolean(key);
    }

    final protected boolean getBooleanFromBundle(String key, boolean defaultValue) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defaultValue;
        }
        return bundle.getBoolean(key, defaultValue);
    }

    final protected boolean getBooleanFromBundle(String key, boolean defaultValue, boolean remove) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defaultValue;
        }
        boolean value = bundle.getBoolean(key, defaultValue);
        if (remove) {
            bundle.remove(key);
        }
        return value;
    }

    protected Application getApplication() {
        Activity activity = activity();
        if (activity != null && !activity.isFinishing()) {
            return activity.getApplication();
        } else {
            return null;
        }
    }

    protected void goToActivity(Class<?> t) {
        goToActivity(t, null, null);
    }

    protected void goToActivity(Class<?> t, String key, String value) {
        Intent intent = new Intent(getActivity(), t);
        if (!TextUtils.isEmpty(key)) {
            intent.putExtra(key, value);
        }
        startActivity(intent);
    }

    protected void goToActivity(Class<?> t, @NonNull Bundle args) {
        Intent intent = new Intent(getActivity(), t);
        if (args != null) {
            intent.putExtras(args);
        }
        startActivity(intent);
    }

    protected void goToActivity(Class<?> t, Intent intent) {
        intent.setClass(activity(), t);
        startActivity(intent);
    }

    protected void goToActivityWithResult(Class<?> t, int requestCode) {
        Intent intent = new Intent(getActivity(), t);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void onClick(View view) {
    }


    final public void finish() {
        Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
            activity.finish();
        }
        onFinish();
    }

    protected void onFinish() {

    }

    final protected void runOnUiThread(Runnable runnable) {
        Activity activity = getActivity();
        if (activity != null) {
            activity.runOnUiThread(runnable);
        }
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    @Override
    public boolean onBackPressed() {
        return false;
    }

    @Override
    final public void onResume() {
        super.onResume();
        _onResumeFragment();
        onResumeFragment();
    }

    protected void _onResumeFragment() {
    }

    protected void onResumeFragment() {
    }

    final public void onPause() {
        super.onPause();
        _onPauseFragment();
        onPauseFragment();
    }

    protected void _onPauseFragment() {
    }

    protected void onPauseFragment() {
    }

    @Override
    final public void onStop() {
        super.onStop();
        _onStopFragment();
        onStopFragment();
    }

    protected void _onStopFragment() {
    }

    protected void onStopFragment() {
    }

    @Override
    final public void onStart() {
        super.onStart();
        _onStartFragment();
        onStartFragment();
    }

    protected void _onStartFragment() {
    }

    protected void onStartFragment() {
    }

    @Override
    final public void onDetach() {
        dismissLoading();
        _onDetachFromActivity();
        onDetachFromActivity();
        super.onDetach();
    }

    protected void _onDetachFromActivity() {
    }

    protected void onDetachFromActivity() {
    }

    @Override
    final public void onDestroy() {
        _onDestroyFragment();
        onDestroyFragment();
        super.onDestroy();
    }

    protected void _onDestroyFragment() {
    }

    protected void onDestroyFragment() {
    }
}
